package ru.jexp.rcp.supply.view;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.viewers.IViewerObservableValue;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

import ru.jexp.obekt.identifikacia.IIdentificiruemii;
import ru.jexp.rcp.supply.ResultWrapper;
import ru.jexp.rcp.supply.beans.IBeanConverter;
import ru.jexp.rcp.supply.editor.EditorInputBean;
import ru.jexp.rcp.supply.img.JExpImageLink;
import ru.jexp.rcp.supply.n.form.Mode;
import ru.jexp.rcp.supply.swtext.IColumnCreator;
import ru.jexp.rcp.supply.swtext.factory.JExpLayoutFactory;
import ru.jexp.rcp.supply.viewer.search.JExpSearchPanel;

public abstract class AbstractViewPart<ColumnT, ViewerT extends ColumnViewer> extends ViewPart
{
	protected abstract ViewerT createViewer(Composite parent);

	protected abstract void createColumns(IColumnCreator<ColumnT, ViewerT> creator, ViewerT viewer);

	protected abstract void openEditor(IIdentificiruemii fullBean) throws PartInitException;
	
	protected abstract void add(IIdentificiruemii liteBean, IObservableValue input);
	
	protected abstract void edit(IIdentificiruemii liteBean, IObservableValue input);
	
	protected abstract void remove(IIdentificiruemii liteBean, IObservableValue input);
	
	private JExpSearchPanel search;
	private ViewerT viewer;

	@SuppressWarnings("unused")
	private String idPart;
	private String namePart;
	private IColumnCreator<ColumnT, ViewerT> columnCreator;
	private IViewerObservableValue selection;

	private IBeanConverter beanConverter;
	private IObservableValue input;

	public AbstractViewPart(String idPart, String namePart, IBeanConverter beanConverter, IColumnCreator<ColumnT, ViewerT> columnCreator)
	{
		this.idPart = idPart;
		this.namePart = namePart;
		this.beanConverter = beanConverter;
		this.columnCreator = columnCreator;
	}

	@Override
	public void init(IViewSite site) throws PartInitException
	{
		super.init(site);
		setPartName(namePart);
		setTitleToolTip(getPartName());
		setTitleImage(JExpImageLink.getImage(JExpImageLink.VIEW_LIST));
	}

	@Override
	public void createPartControl(Composite parent)
	{
		parent.setLayout(new GridLayout(2, false));
		search = new JExpSearchPanel(parent);

		viewer = createViewer(parent);
		createColumns(columnCreator, viewer);
		viewer.getControl().setLayoutData(JExpLayoutFactory.gdFillBothWithHorizontalSpan(2));
		viewer.addDoubleClickListener(new IDoubleClickListener()
		{
			@Override
			public void doubleClick(DoubleClickEvent event)
			{
				onEdit();
			}
		});

		search.setViewer(viewer);

		initObservables();
		initData();
	}

	@Override
	public void setFocus()
	{
		search.setFocus();
	}
	
	public void refresh(EditorInputBean editorInput)
	{
		IIdentificiruemii liteBean = beanConverter.toLite((IIdentificiruemii) editorInput.getEditBean());
		if (Mode.ADD == editorInput.getMode())
		{
			add(liteBean, input);
		}
		if (Mode.EDIT == editorInput.getMode())
		{
			edit(liteBean, input);
		}
		if (Mode.DELETE == editorInput.getMode())
		{
			remove(liteBean, input);
		}
		viewer.refresh();
	}

	protected void onEdit()
	{
		try
		{
			openEditor(beanConverter.toFull((IIdentificiruemii) selection.getValue()));
		}
		catch (PartInitException e)
		{
			e.printStackTrace();
		}
	}

	private void initObservables()
	{
		selection = ViewersObservables.observeSinglePostSelection(viewer);
		input = ViewersObservables.observeInput(viewer);
	}
	
	private void initData()
	{
		input.setValue(ResultWrapper.searchList(beanConverter.getFullType()));
	}
}
